from IPython.display import HTML
HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')
23-03-2020 8:00 a.m a 23-03-2020 3:0 p.m
NOTA: Debido a problemas con la conexión de internet la red dejó de construirse entre 11:00 a.m y 2:30 p.m. Por esto, esta fuente puede estar incompleta. Las demás fuentes:(Facebook,Instagram y Tuits realizados en el periodo de tiempo no se vieron comprometidas.
Construí una red que representa las interacciones de los usuarios de Twitter que publican tuits con los hashtags "simulacrovital","bogotasequedaencasa","simulacrodeaislamiento","cuarentenaobligatoria bogota", "cuarentenaobligatoria bogotá","yomequedoencasa bogota","yomequedoencasa bogotá","quedateencasa bogotá", "quedateencasa bogota" y descargué los tuits asociados al tema. La extracción de datos se realiza en tiempo real con la API Twitter Standar Stream. Con métodos de análisis de redes y text mining detecté los influenciadores y temas más importantes en esta conversación. Este ejercicio puede replicarse monitoreando cualquier otra palabra clave, hashtag o usuario.
Revisé los posts en Facebook e Instagram con más interacciones que incluyen la palara Bogotá y fueron realizados en el periodo de tiempo analizado. Este ejercicio se realizó con CrowdTangle.
DISCLAIMER: Este archivo se escribe en 15 minutos. Me disculpo por posibles errores de redacción y ortografía.
En Twitter el mensaje principal de la conversación es la promoción del diligenciamiento del cuestionario de entrada a Bogotá. La información sobre las medidas de los próximos días es secundaria. La preocupación por los animales sigue vigente.
Hay dos comunidades pequeñas, pero con más de 5% de los nodos, que cuestionan (sin criticar directamente) el simulacro replicando mensajes de fuentes no oficiales (@penalosadas o @bogota__dc, por ejemplo)y de figuras públicas como Petro y Morris.
En Facebook los temas que generan más reacciones son **la sanción social a infractores del Simulacro en Cedritos, el reporte de casos confirmados de MinSalud y la crítica de Claudia López al decreto presidencial.
En Instagram los posts más populares relacionados con la coyuntura son el reporte de casos confirmados y la publicación de la alcaldesa promoviendo que los ciudadanos que vuelven a la ciudad diligencien el formulario. En Instragram el Simulacro de Bogotá no es muy popular
import json
from bson.json_util import dumps, CANONICAL_JSON_OPTIONS
from bson import Binary, Code
from collections import Counter, OrderedDict
import pyperclip
import spacy
from wordcloud import WordCloud
from stop_words import get_stop_words
import string
import altair as alt
import matplotlib.pyplot as plt
nlp=spacy.load('es_core_news_sm')
import pandas as pd
stopwords_es= get_stop_words('es')
import pandas as pd
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import collections
import tweepy
import csv
import operator
import community
from IPython.display import Markdown,display
from datetime import datetime
import dateutil
display(Markdown(str("## Los post de Facebook con la palabra Bogotá que más interacciones tuvieron en este periodo de tiempo fueron:")))
Image(filename='./9_Facebook.png')
display(Markdown(str("## Los post de Instagram con la palabra Bogotá que más interacciones tuvieron en este periodo de tiempo fueron")))
Image(filename='./9_Instagram.png')
from pymongo import MongoClient
client = MongoClient()
db = client.corona
G=nx.read_graphml("/home/laufernanda/Documents/corona-redes/simulacro9.graphml")
print('La red tiene ',G.number_of_nodes(),'usuarios y ',G.number_of_edges(),"interacciones")
from IPython.display import Image
Image(filename='image9.png')
G= nx.DiGraph(G)
#centrality = nx.eigenvector_centrality(G)
for node in G.nodes():
G.nodes[node]["in_degree"]=G.in_degree[node]
G.nodes[node]["out_degree"]=G.out_degree[node]
#G.nodes[node]["eigenvector"]=centrality[node]
H=G.to_undirected()
partition=community.best_partition(H)
for node in G.nodes() :
G.node[node]['comunidad']= partition[node]
#Análisis comunidades
#Tamano comunidades
c=Counter(list(partition.values()))
c=OrderedDict(c.most_common())
n=G.number_of_nodes()/20
comunidades_importantes=[]
for k in c.keys():
if c[k]>= n:
comunidades_importantes.append(k)
print("La red tiene ", len(comunidades_importantes), " comunidades importantes (tienen más del 5% de los nodos)" )
top_reacciones={}
top_creadores={}
top_influencers={}
grado_in=sorted(G.in_degree(),key=operator.itemgetter(1),reverse=True)
for comunidad in comunidades_importantes:
nodos_comunidad=[node for node in G.nodes() if G.nodes[node]['comunidad']==comunidad]
grado_in=sorted(G.in_degree(nodos_comunidad),key=operator.itemgetter(1),reverse=True)
grado_out=sorted(G.out_degree(nodos_comunidad),key=operator.itemgetter(1),reverse=True)
eigen={k:v for k,v in centrality.items() if k in nodos_comunidad}
eigen=sorted(eigen,key=operator.itemgetter(1),reverse=True)
top_reacciones[comunidad]=[x[0] for x in grado_in[0:5]]
top_creadores[comunidad]=[x[0] for x in grado_out[0:5]]
top_influencers[comunidad]=eigen[0:5]
De la comunidad con más nodos (usuarios) a la de menos:
(Azul en la gráfica )Es una comunidad de Preocupación ciudadana por el bienestar de los animales. Solicitan vigilancia en las Plazas de mercado de la ciudad y apoyo para protección de animales sin hogar. @juliherrerap es un nodo clave en esta comunidad.
(Verde en la gráfica) Es una comunidad de difusión de los resultados positivos de calidad del aire promoción del diligenciamento del cuestionario para ciudadanos que salieron de la ciudad por parte de fuentes oficiales..
(Rosado en la gráfica) Es una comunidad de difusión de información oficial regional (Cundinamarca-Bogotá) enfocada en la difusión del cuestionario para quienes salieron de Bogotá.La cuenta del gobernador de Cundinamarca y la alcaldía de Bogotá hacen parte de esta comunidad.
(Rojo en la gráfica) Es una comunidad compuesta por entidades del distrito de difusión de las medidas que se tomarán en la ciudad durante la cuarentena
(Naranja en la gráfica) Es una comunidad liderada por medios de difusión de información del desarrollo del simulacro. Este mensaje, dentro de los más retuiteados, puede merecer atención especial: Pequeño comerciante del barrio Acevedo Tejada de Teusaquillo en Bogotá, dice que no es cierto que haya mucho mercado en Corabastos, q hay pocos puestos abiertos con escasos productos, y con precios muy elevados. Posible acaparamiento en inicio de cuarentena @ClaudiaLopez @Bogota
import pytz
start = datetime(2020, 3, 23, 13, 00, 00, 0, pytz.UTC)
end = datetime(2020, 3, 23, 18, 00, 00, 0, pytz.UTC)
count=0
for comunidad in comunidades_importantes:
count+=1
display(Markdown(str("## Comunidad "+ str(count) + ":")))
display(Markdown(str("**La comunidad "+ str(count)+ " tiene "+ str(c[comunidad])+" usuarios**")))
display(Markdown(str("**La comunidad "+ str(count)+ " habla de:**")))
nodos_comunidad=[node for node in G.nodes() if G.nodes[node]['comunidad']==comunidad]
nodos_comunidad=[sub.replace('@', '') for sub in nodos_comunidad]
tw_iter=db.simulacro.find({"user.screen_name":{"$in":nodos_comunidad}})
text=[]
ids_filtrados=[]
for tweet in tw_iter:
tw=tweet
date_tuit=dateutil.parser.parse(tw["created_at"])
if(start<date_tuit< end):
ids_filtrados.append(tw['_id'])
text.append(tweet["text"])
if len(text)>=1:
text_s=" ".join(text)
text_s=text_s.replace("https"," ")
text_s=text_s.replace("RT"," ")
wordcloud = WordCloud(scale=2, max_words=2000,relative_scaling=0.5,background_color ='white',stopwords=stopwords_es).generate(text_s)
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
print("Se incluyeron ",len(text), "tuits producidos por nodos de esta comunidad en el intervalo de tiempo analizado.")
display(Markdown(str("**los usuarios que son más retuiteados, mencionados o citados en la comunidad "+ str(count) + " son:**"+
", ".join(top_reacciones[comunidad]))))
print("__________________________________________________________________________________________________________________")
display(Markdown(str("**los usuarios que retuitean, mencionan y citan más en la comunidad "+ str(count) + " son:**"+
", ".join(top_creadores[comunidad]))))
#print("__________________________________________________________________________________________________________________")
#display(Markdown(str("**los usuarios con mayor influencia en la comunidad "+ str(comunidad) + " son:**"+
# ", ".join(top_influencers[comunidad]))))
#print("__________________________________________________________________________________________________________________")
display(Markdown(str("**los trinos más retuiteados de la comunidad "+ str(count) + " son:**")))
nodos_comunidad=[node for node in G.nodes() if G.nodes[node]['comunidad']==comunidad]
nodos_comunidad=[sub.replace('@', '') for sub in nodos_comunidad]
#Top most retweeted tweets
tw_iter_RT = db.simulacro.aggregate([
{"$match": {
"$and":[ {"retweeted_status": {"$exists": True}},
{"_id":{"$in":ids_filtrados}}
]}},
{"$replaceRoot": { "newRoot": "$retweeted_status" }},
{"$group" : {"_id":"$id",
"text":{"$last":"$extended_tweet.full_text"},
"username":{"$last":"$user.screen_name"},
"count":{"$sum":1}}},
{"$sort": {"count": -1}}
])
try:
top = [tw_iter_RT.next() for i in range(10)]
df= pd.DataFrame(top)
pd.set_option("max_colwidth",300)
display(df)
except:
top = list(tw_iter_RT)
df= pd.DataFrame(top)
display(df)
print("no hay suficiente info disponible")
display(Markdown(str("**los hashtags más usados en la comunidad "+ str(count) + " son:**")))
#Hashtgas
#Top most used hashtags
tw_iter_HT = db.simulacro.aggregate([
{"$match":{"_id":{"$in":ids_filtrados}}},
{"$unwind": "$entities.hashtags"},
{"$group" : {"_id":"$entities.hashtags.text",
"count":{"$sum":1}}},
{"$sort": {"count": -1}}
])
try:
top = [tw_iter_HT.next() for i in range(5)]
df= pd.DataFrame(top)
display(df)
except:
top = list(tw_iter_HT)
df= pd.DataFrame(top)
display(df)
print("no hay suficiente info disponible")
usuarios_importantes=[]
for comunidad in comunidades_importantes:
usuarios_importantes.extend(top_reacciones[comunidad])
usuarios_importantes.extend(top_creadores[comunidad])
#usuarios_importantes.extend(top_influencers[comunidad])
usuarios_importantes=set(usuarios_importantes)
f = open("./twitteros_importantes_conversación_simulacro2.txt", "a")
for line in usuarios_importantes:
f.write(line)
f.write("\n")
print(line)
f.close()